package com.example.demo.service.impl;

import com.example.demo.controller.PersonalDashboardVO;
import com.example.demo.controller.CourseProgressVO;
import com.example.demo.entity.StudentProgress;
import com.example.demo.entity.StudentCourse;
import com.example.demo.mapper.StudentProgressMapper;
import com.example.demo.mapper.StudentCourseMapper;
import com.example.demo.service.PersonalDashboardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
public class PersonalDashboardServiceImpl implements PersonalDashboardService {

    @Autowired
    private StudentProgressMapper studentProgressMapper;

    @Autowired
    private StudentCourseMapper studentCourseMapper;

    @Override
    public PersonalDashboardVO getPersonalDashboard(Long studentId) {
        PersonalDashboardVO dashboard = new PersonalDashboardVO();
        dashboard.setStudentId(studentId);
        dashboard.setStudentName(getStudentName(studentId));

        // 计算总得分和排名
        calculateTotalScoreAndRanking(studentId, dashboard);

        // 计算能力维度数据
        calculateCompetencyDimensions(studentId, dashboard);

        // 计算总体任务进度
        calculateOverallProgress(studentId, dashboard);

        // 获取课程进度列表
        getStudentCourseProgressList(studentId, dashboard);

        return dashboard;
    }

    @Override
    public CourseProgressVO getCourseProgress(Long studentId, Long courseId) {
        CourseProgressVO progress = new CourseProgressVO();
        progress.setStudentId(studentId);
        progress.setCourseId(courseId);
        progress.setCourseName(getCourseName(courseId));

        // 获取该课程的所有进度记录
        List<StudentProgress> progresses = studentProgressMapper.findByStudentIdAndCourseId(studentId, courseId);

        // 计算课程得分
        Double courseScore = progresses.stream()
                .filter(p -> p.getScore() != null)
                .mapToDouble(StudentProgress::getScore)
                .average()
                .orElse(0.0);
        progress.setScore(Math.round(courseScore * 100.0) / 100.0);

        // 计算完成率
        long totalAssignments = progresses.size();
        long completedAssignments = progresses.stream()
                .filter(p -> isCompleted(p.getCompletionStatus()))
                .count();
        double completionRate = totalAssignments > 0 ? (double) completedAssignments / totalAssignments * 100 : 0.0;
        progress.setCompletionRate(Math.round(completionRate * 100.0) / 100.0);

        // 设置任务统计
        progress.setTotalAssignments((int) totalAssignments);
        progress.setCompletedAssignments((int) completedAssignments);
        progress.setInProgressAssignments((int) progresses.stream()
                .filter(p -> isInProgress(p.getCompletionStatus()))
                .count());
        progress.setNotStartedAssignments((int) progresses.stream()
                .filter(p -> isNotStarted(p.getCompletionStatus()))
                .count());

        return progress;
    }

    @Override
    public void calculateTotalScoreAndRanking(Long studentId, PersonalDashboardVO dashboard) {
        // 获取学生的所有进度记录
        List<StudentProgress> allProgresses = studentProgressMapper.findByStudentId(studentId);

        // 计算总得分
        Double totalScore = allProgresses.stream()
                .filter(progress -> progress.getScore() != null)
                .mapToDouble(StudentProgress::getScore)
                .sum();
        dashboard.setTotalScore(Math.round(totalScore * 100.0) / 100.0);

        // 计算总排名（简化实现）
        Integer totalRanking = calculateStudentRanking(studentId, totalScore);
        dashboard.setTotalRanking(totalRanking);

        // 统计课程数 - 使用 StudentCourseMapper 获取学生选课记录
        List<StudentCourse> studentCourses = studentCourseMapper.findByStudentId(studentId.toString());
        dashboard.setTotalCourses(studentCourses.size());

        // 统计完成课程数（完成率超过80%视为完成）
        long completedCourses = studentCourses.stream()
                .filter(course -> "completed".equals(course.getEnrollmentStatus()))
                .count();
        dashboard.setCompletedCourses((int) completedCourses);
    }

    @Override
    public void calculateCompetencyDimensions(Long studentId, PersonalDashboardVO dashboard) {
        // 模拟能力维度数据（实际项目中需要根据业务逻辑计算）
        Map<String, Double> competencyDimensions = new HashMap<>();
        competencyDimensions.put("编程能力", 85.0);
        competencyDimensions.put("算法思维", 78.0);
        competencyDimensions.put("项目实践", 92.0);
        competencyDimensions.put("团队协作", 88.0);
        competencyDimensions.put("创新能力", 75.0);
        competencyDimensions.put("问题解决", 82.0);

        dashboard.setCompetencyDimensions(competencyDimensions);
    }

    @Override
    public void calculateOverallProgress(Long studentId, PersonalDashboardVO dashboard) {
        List<StudentProgress> allProgresses = studentProgressMapper.findByStudentId(studentId);

        PersonalDashboardVO.ProgressInfo progressInfo = new PersonalDashboardVO.ProgressInfo();

        progressInfo.setTotalAssignments(allProgresses.size());
        progressInfo.setCompletedAssignments((int) allProgresses.stream()
                .filter(p -> isCompleted(p.getCompletionStatus()))
                .count());
        progressInfo.setInProgressAssignments((int) allProgresses.stream()
                .filter(p -> isInProgress(p.getCompletionStatus()))
                .count());
        progressInfo.setNotStartedAssignments((int) allProgresses.stream()
                .filter(p -> isNotStarted(p.getCompletionStatus()))
                .count());

        // 计算完成率
        double completionRate = allProgresses.size() > 0 ?
                (double) progressInfo.getCompletedAssignments() / allProgresses.size() * 100 : 0.0;
        progressInfo.setCompletionRate(Math.round(completionRate * 100.0) / 100.0);

        dashboard.setOverallProgress(progressInfo);
    }

    @Override
    public void getStudentCourseProgressList(Long studentId, PersonalDashboardVO dashboard) {
        // 获取学生参与的所有课程 - 使用 StudentCourseMapper
        List<StudentCourse> studentCourses = studentCourseMapper.findByStudentId(studentId.toString());

        List<PersonalDashboardVO.CourseProgressItem> courseProgressList = new ArrayList<>();

        for (StudentCourse studentCourse : studentCourses) {
            Long courseId = Long.parseLong(studentCourse.getCourseId());
            CourseProgressVO courseProgress = getCourseProgress(studentId, courseId);

            PersonalDashboardVO.CourseProgressItem item = new PersonalDashboardVO.CourseProgressItem();
            item.setCourseId(courseId);
            item.setCourseName(courseProgress.getCourseName());
            item.setScore(courseProgress.getScore());
            item.setCompletionRate(courseProgress.getCompletionRate());
            item.setStatus("completed".equals(studentCourse.getEnrollmentStatus()) ? "已完成" : "进行中");

            courseProgressList.add(item);
        }

        dashboard.setCourseProgressList(courseProgressList);
    }

    // ========== 私有辅助方法 ==========

    private boolean isCompleted(StudentProgress.CompletionStatus status) {
        return status != null && status == StudentProgress.CompletionStatus.COMPLETED;
    }

    private boolean isInProgress(StudentProgress.CompletionStatus status) {
        return status != null && status == StudentProgress.CompletionStatus.IN_PROGRESS;
    }

    private boolean isNotStarted(StudentProgress.CompletionStatus status) {
        return status != null && status == StudentProgress.CompletionStatus.NOT_STARTED;
    }

    private Integer calculateStudentRanking(Long studentId, Double totalScore) {
        // 简化实现：这里应该查询所有学生的总得分并计算排名
        // 实际项目中需要根据年级或班级来排名
        return 5; // 临时返回第5名
    }

    private String getStudentName(Long studentId) {
        // 这里需要调用学生服务或查询学生表
        // 简化返回学生ID
        return "学生_" + studentId;
    }

    private String getCourseName(Long courseId) {
        // 这里需要调用课程服务或查询课程表
        // 简化返回课程ID
        return "课程_" + courseId;
    }
}